﻿namespace Refract.Data
{
    using System;
    using System.Collections.Generic;

    using Refract.Event;
    using Refract.MVVM;

    /// <summary>
    /// Base class for readonly data services
    /// </summary>
    /// <typeparam name="TEntity">The type of the entity.</typeparam>
    /// <typeparam name="TListEntity">The type of the list entity.</typeparam>
    /// <typeparam name="TListModel">The type of the list model.</typeparam>
    public abstract class ReadOnlyDataService<TEntity, TListEntity, TListModel> : Component, IReadOnlyDataService<TEntity, TListEntity, TListModel>
        where TEntity : class, new()
        where TListEntity : IEnumerable<TEntity>, new()
        where TListModel : Model<TListEntity>, new()
    {
        #region Fields

        private bool _isBusy;
        private int _processCount;

        #endregion Fields

        #region Events

        /// <summary>
        /// Occurs when an entity list load operation is complete.
        /// </summary>
        public event EventHandler<EventArgs<TListEntity>> EntityListLoadComplete;

        /// <summary>
        /// Occurs when an entity load operation is complete.
        /// </summary>
        public event EventHandler<EventArgs<TEntity>> EntityLoadComplete;

        #endregion Events

        #region Properties

        /// <summary>
        /// Gets or sets a value indicating whether this service is busy.
        /// </summary>
        /// <value><c>true</c> if this instance is busy; otherwise, <c>false</c>.</value>
        public bool IsBusy
        {
            get { return _isBusy; }
            set
            {
                _isBusy = value;
                RaisePropertyChanged(new { IsBusy });
            }
        }

        /// <summary>
        /// Gets or sets the pending process count.
        /// </summary>
        /// <value>The process count.</value>
        public int ProcessCount
        {
            get { return _processCount; }
            protected set
            {
                _processCount = value;
                IsBusy = _processCount > 0;
                RaisePropertyChanged(new { ProcessCount });
            }
        }

        #endregion Properties

        #region Methods

        /// <summary>
        /// Gets a list of all records for this entity.
        /// </summary>
        /// <returns></returns>
        public abstract TListModel GetList();

        /// <summary>
        /// Raises the entity list load complete event.
        /// </summary>
        /// <param name="entity">The entity.</param>
        protected void RaiseEntityListLoadComplete(TListEntity entity)
        {
            if (EntityListLoadComplete != null) EntityListLoadComplete(this, new EventArgs<TListEntity>(entity));
        }

        /// <summary>
        /// Raises the entity load complete event.
        /// </summary>
        /// <param name="entity">The entity.</param>
        protected void RaiseEntityLoadComplete(TEntity entity)
        {
            if(EntityLoadComplete != null) EntityLoadComplete(this, new EventArgs<TEntity>(entity));
        }

        #endregion Methods
    }
}